#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <assert.h>
// 引入程序正常运行的一些外部依赖，在程序编译的时候替换
#include <stdbool.h>

// define定义相应的宏常量与宏函数。
#define BOOL_TRUE 1
#define BOOL_FALSE 0
// _Generic 使用宏的泛型
#define typename(x) _Generic((x)
    ,unsigned short:"unsigned short int"
    ,unsigned long:"unsigned long int"
    ,default:"unknown")

typedef enum {Host,IP} IP_ADDR_TYPE;
typedef struct {
    size_t id;
    uint16_t port;
    bool closed;
    IP_ADDR_TYPE addr_type;
    union {
        char host_name[256];
        char ip[24];
    };
} CONN;

// inline 关键字，将函数的内部逻辑直接替换到函数的调用位置
inline static const char* findAddr(const CONN* pip) {
    // 使用了c11标准中的静态断言能力，保证conn的大小不会超过一定的阈值
    assert(pip != NULL);
    return pip->addr_type == Host ? pip -> host_name : pip->ip;
}

// 入口函数 返回值表达0 表示正常退出，其他数值表示异常退出 EXIT_SUCCESS常量0
int main(int argc, char* argv[]) {
    static_assert(sizeof(CONN) <= 0x400, "the size of CONN object exceeds limit.")
    //数组初始化
    const CONN conns[] = { // 构造一个数组，包含三个 CONN 对象；
    // { .ip = "127.0.0.1" } .符号引用某个具体成员，而非数组的使用形势
     [2] = { 1, 80, BOOL_TRUE, IP, { .ip = "127.0.0.1" } },
     [0] = { 2, 8080, BOOL_FALSE, IP, { .ip = "192.168.1.1" } },
     { 3, 8088, BOOL_FALSE, Host, { .host_name = "http://localhost/" } } };

    // 访问内部存放元素  直接使用方括号加索引值的语法实现
    // 常用的控制语句 switch while goto 语句
    // 选择 迭代与跳转
    for (size_t i = 0; i < (sizeof(conns) / sizeof(CONN)); ++i) {
        // 遍历上述 CONN 数组，并打印其中的内容；
         printf( "Port: %d\n"
         "Host/Addr: %s\n"
         "Internal type of `id` is: %s\n\n",
         conns[i].port,
         // &传递指针 无法在函数内部修改指针所指向对象的值
         findAddr(&conns[i]),
         typename(conns[i].id)
         );
     }
     return EXIT_SUCCESS;
}

//其它特性， const 只读变量； typedef定义新类型；static 声明静态函数
// 使用各类运算符，调用标准库函数，使用enum定义枚举类型

// C语言的编程范式 命令式编程语言
//那个可以改变程序状态的代码语句，描述程序应该如何运行，
#define ARR_LEN 5
int main(void) {
  int arr[ARR_LEN] = { 1, 5, 10, 9, 0 };
  for (int i = 0; i < ARR_LEN; ++i) {
    if (arr[i] > 7) {
      // save this element somewhere else.
    }
  }
  return 0;
}
// 声明式编程语句：
//倾向于表达计算的逻辑，而非解决问题时计算机需要执行的具体步骤
let arr = [1, 5, 10, 9, 0]
let result = arr.filter(n => n > 7)

//gcc 编译
gcc demo.c -o demo -Wall && ./demo

//编译过程
// c代码编译-》代码预处理（移除注释，处理宏指令）-》
//编译优化（分析并优化代码，生成汇编代码）->汇编（生成对象格式文件）->链接(地址重定位，
//生成二进制可执行文件)
